home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / ddj0897.zip / DYN401.ZIP / dpp / proto.d < prev    next >
Text File  |  1996-12-08  |  10KB  |  487 lines

  1.  
  2. /*
  3.  *
  4.  *    Copyright (c) 1994-1996 Algorithms Corporation
  5.  *    3020 Liberty Hills Drive
  6.  *    Franklin, TN  37067
  7.  *
  8.  *    ALL RIGHTS RESERVED.
  9.  *
  10.  *
  11.  *
  12.  */
  13.  
  14.  
  15.  
  16. #include <ctype.h>
  17. #include <string.h>
  18.  
  19. #include "dpp.h"
  20.  
  21. defclass  Prototype  {
  22.     iName;            /*  method/generic name            */
  23.     iFixedName;        /*  associated fixed arg name        */
  24.     iRtn;            /*  return type                */
  25.     iArgs;            /*  list of args with vars & types     */
  26.     iProto;            /*  args without vars            */
  27.     iParams;        /*  argument parameters without types    */
  28.     int    iVararg;    /*  1=various methods associated with the same
  29.                     generic may have different args     */
  30.     int    iException;    /*  1=no arg checking for this proto      */
  31.     int    iNeedRest;    /*  vararg _rest_ variable needed    */
  32.     object    iLastArg;    /*  last arg prior to ...        */
  33. };
  34.  
  35.  
  36. #define strne(a, b)    strcmp(a, b)
  37. #define streq(a, b)    !strcmp(a, b)
  38.  
  39. #define istart(x)    (isalpha(x)  ||  (x) == '_')
  40. #define irest(x)    (isalnum(x)  ||  (x) == '_')
  41.  
  42.  
  43. extern    char    *trunc_mname(char *mname);
  44.  
  45.  
  46. cmeth    gNew()
  47. {
  48.     return gShouldNotImplement(self, "gNew");
  49. }
  50.  
  51. cmeth    gNewWithStrStr(char *nm, char *rt)
  52. {
  53.     object    obj = gNew(super);
  54.     ivType    *iv = ivPtr(obj);
  55.     iName = gNewWithStr(String, nm);
  56.     iRtn  = gNewWithStr(String, rt);
  57.     return obj;
  58. }
  59.  
  60. imeth    object    gDispose, gDeepDispose ()
  61. {
  62.     gDispose(iName);
  63.     if (iFixedName)
  64.         gDispose(iFixedName);
  65.     gDispose(iRtn);
  66.     if (iArgs)
  67.         gDeepDispose(iArgs);
  68.     if (iProto)
  69.         gDeepDispose(iProto);
  70.     if (iParams)
  71.         gDeepDispose(iParams);
  72.     if (iLastArg)
  73.         gDeepDispose(iLastArg);
  74.     return gDispose(super);
  75. }
  76.  
  77. imeth    int    gHash()
  78. {
  79.     return gHash(iName);
  80. }
  81.  
  82. imeth    int    gCompare(object obj)
  83. {
  84.     ChkArgTyp(obj, 2, CLASS);
  85.     return gCompare(iName, ivPtr(obj)->iName);
  86. }
  87.  
  88. static    void    remove_variable(char *buf, char *var)
  89. {
  90.     register int    i, vi = -1;
  91.  
  92.     for (i=0 ; buf[i] ; )
  93.         if (istart(buf[i]))  {
  94.             vi = i++;
  95.             while (buf[i]  &&  irest(buf[i]))
  96.                 i++;
  97.         } else
  98.             i++;
  99.     
  100.     if (vi >= 0)  {
  101.         for (i=vi ; irest(buf[i]) ; )
  102.             *var++ = buf[i++];
  103.         if (vi  &&  buf[vi-1] == ' ')
  104.             vi--;
  105.         for (i=vi+1 ; buf[i]  &&  irest(buf[i]) ; i++);
  106.         memmove(buf+vi, buf+i, strlen(buf+i) + 1);
  107.     }
  108.     *var = '\0';
  109. }
  110.  
  111. static    void    make_proto(ivType *iv, object ar)
  112. {
  113.     object    seq, nxt, prv=NULL;
  114.     char    buf[100], var[50];
  115.  
  116.     iProto = gNew(LinkObject);
  117.     iParams = gNew(LinkObject);
  118.     for (seq=gSequence(ar) ; nxt = gNext(seq) ; )  {
  119.         strcpy(buf, gStringValue(nxt));
  120.         remove_variable(buf, var);
  121.         gAddLast(iProto, gNewWithStr(String, buf));
  122.         if (!*var)  {    /*  arg must have been ...   */
  123.             iNeedRest = 1;
  124.             if (iLastArg)
  125.                 DISPOSE(iLastArg);
  126.             iLastArg = prv ? gCopy(prv) : prv;
  127.         }
  128.         gAddLast(iParams, prv=gNewWithStr(String, *var ? var : "_rest_"));
  129.     }
  130. }
  131.  
  132. imeth    gPrintArgs(object fobj)
  133. {
  134.     object    seq, nxt;
  135.     int    n=0;
  136.  
  137.     if (iArgs  &&  !iVararg  &&  !iException)
  138.         for (seq=gSequence(iArgs) ; nxt = gNext(seq) ; )  {
  139.             if (n++)
  140.                 gPuts(fobj, ", ");
  141.             gPuts(fobj, (char *) nxt);
  142.         }
  143.     else
  144.         gPuts(fobj, "object self, ...");
  145.     return self;
  146. }
  147.  
  148. imeth    gPrintFixedArgs(object fobj)
  149. {
  150.     object    seq, nxt;
  151.     int    n=0;
  152.  
  153.     if (iArgs)
  154.         for (seq=gSequence(iArgs) ; nxt = gNext(seq) ; )  {
  155.             if (n++)
  156.                 gPuts(fobj, ", ");
  157.             gPuts(fobj, (char *) nxt);
  158.         }
  159.     else
  160.         gPuts(fobj, "object self, ...");
  161.     return self;
  162. }
  163.  
  164. imeth    gPrintMethArgs(object fobj, int Strategy, int vararg)
  165. {
  166.     object    seq, nxt;
  167.     int    n=0;
  168.  
  169.     if (vararg  &&  Strategy != 1)  {
  170.         gPut(fobj, gNewToken(Token, "object self", 0L, 0));
  171.         gPut(fobj, gNewToken(Token, ",", 0L, 1));
  172.         gPut(fobj, gNewToken(Token, "va_list _rest_", 0L, 0));
  173.     } else if (iArgs)
  174.         for (seq=gSequence(iArgs) ; nxt = gNext(seq) ; )  {
  175.             if (n++)
  176.                 gPut(fobj, gNewToken(Token, ",", 0L, 1));
  177.             if (Strategy > 1  &&  streq(gStringValue(nxt), "..."))
  178.                 gPut(fobj, gNewToken(Token, "va_list _rest_", 0L, 0));
  179.             else
  180.                 gPut(fobj, gNewToken(Token, gStringValue(nxt), 0L, 0));
  181.         }
  182.     gPut(fobj, gNewToken(Token, ")", 0L, 0));
  183.     return self;
  184. }
  185.  
  186. imeth    gPrintVars(object fobj)
  187. {
  188.     object    seq, nxt;
  189.     int    n=0;
  190.     char    *v;
  191.  
  192.     if (iParams  &&  !iVararg  &&  !iException)
  193.         for (seq=gSequence(iParams) ; nxt = gNext(seq) ; )  {
  194.             if (n++)
  195.                 gPuts(fobj, ", ");
  196.             v = gStringValue(nxt);
  197.             if (*v)
  198.                 gPuts(fobj, (char *) nxt);
  199.             else
  200.                 gPuts(fobj, "_rest_");
  201.         }
  202.     else
  203.         gPuts(fobj, "self, _rest_");
  204.     return self;
  205. }
  206.  
  207. imeth    gUseVars(object fobj)
  208. {
  209.     object    seq, nxt;
  210.     char    *v;
  211.     int    n = 0;
  212.  
  213.     if (!iParams)
  214.         return self;
  215.     for (seq=gSequence(iParams) ; nxt = gNext(seq) ; )
  216.         if (n++)  {
  217.             v = gStringValue(nxt);
  218.             if (*v  &&  strne(v, "_rest_"))
  219.                 vPrintf(fobj, "\tUSE(%s);\n", v);
  220.         }
  221.     return self;
  222. }
  223.  
  224. #if 0
  225.  
  226. static    void    print_args(ivType *iv, object ar)
  227. {
  228.     object    seq, nxt;
  229.     int    n=0;
  230.  
  231.     vPrintf(stdoutStream, "%s %s(", gStringValue(iRtn), gStringValue(iName));
  232.     for (seq=gSequence(ar) ; nxt = gNext(seq) ; )  {
  233.         if (n++)
  234.             gPuts(stdoutStream, ", ");
  235.         gPuts(stdoutStream, (char *) nxt);
  236.     }
  237.     gPuts(stdoutStream, ")\n");
  238.     if (iVararg)
  239.         gPuts(stdoutStream, "Varargs is set\n");
  240.     else
  241.         gPuts(stdoutStream, "Varargs is not set\n");
  242.     if (iException)
  243.         gPuts(stdoutStream, "Exception is set\n");
  244.     else
  245.         gPuts(stdoutStream, "Exception is not set\n");
  246. }
  247.  
  248. #endif
  249.  
  250. imeth    gSetArgs(object ar)
  251. {
  252.     if (iArgs)
  253.         DEEPDISPOSE(iArgs);
  254.     if (iProto)
  255.         iProto = DEEPDISPOSE(iProto);
  256.     if (iParams)
  257.         iParams = DEEPDISPOSE(iParams);
  258.     if (iArgs = ar)
  259.         make_proto(iv, ar);
  260.     if (ar  &&  gSize(ar) == 2  &&  streq(gStringValue(gLast(ar)), "..."))
  261.         iVararg = 1;
  262. #if 0
  263.     print_args(iv, iArgs);
  264.     print_args(iv, iProto);
  265. #endif
  266.     return self;
  267. }
  268.  
  269. imeth    gReturnType()
  270. {
  271.     return iRtn;
  272. }
  273.  
  274. imeth    gArgs()
  275. {
  276.     return iArgs;
  277. }
  278.  
  279. imeth    object    gPrototype()
  280. {
  281.     return iProto;
  282. }
  283.  
  284. imeth    object    gParameters()
  285. {
  286.     return iParams;
  287. }
  288.  
  289. imeth    gDeepCopy()
  290. {
  291.     object    nobj;
  292.     ivType    *niv;
  293.     
  294.     nobj = gDeepCopy(super);
  295.     niv  = ivPtr(nobj);
  296.     niv->iName = gDeepCopy(iName);
  297.     niv->iFixedName = iFixedName ? gDeepCopy(iFixedName) : iFixedName;
  298.     niv->iRtn  = gDeepCopy(iRtn);
  299.     if (iArgs)  {
  300.         niv->iArgs = gDeepCopy(iArgs);
  301.         niv->iProto = gDeepCopy(iProto);
  302.         niv->iParams = gDeepCopy(iParams);
  303.     }
  304.     if (iLastArg)
  305.         niv->iLastArg = gDeepCopy(iLastArg);
  306.     return nobj;
  307. }
  308.  
  309. imeth    int    gMatchNoError(object mproto)
  310. {
  311.     ivType    *miv = ivPtr(mproto);
  312.     object    mseq, gseq, garg, marg;
  313.  
  314. #if 0
  315.     print_args(iv, iArgs);
  316.     print_args(miv, miv->iArgs);
  317. #endif
  318.  
  319.     if (gCompare(miv->iRtn, iRtn))
  320.         return 0;
  321.  
  322.     if ((!miv->iArgs  ||  miv->iVararg  ||  miv->iException)  &&  (!iArgs  ||  iVararg))
  323.         return 1;  /*  both vararg  */
  324.  
  325.     if (miv->iException  ||  !miv->iArgs  ||  miv->iVararg  ||  !iArgs  ||  iVararg)
  326.         return 0;  /*  one is vararg the other not  */
  327.     
  328.     if (gSize(miv->iArgs) != gSize(iArgs))
  329.         return 0;    /*  different number of arguments  */
  330.  
  331.     mseq = gSequence(miv->iArgs);
  332.     gseq = gSequence(iArgs);
  333.     garg = (object) 1;    /*  any non-NULL  */
  334.     while (marg = gNext(mseq))  {
  335.         garg = gNext(gseq);
  336.         if (!garg  ||  gCompare(marg, garg))  {
  337.             DISPOSE(mseq);
  338.             if (garg)
  339.                 DISPOSE(gseq);
  340.             return 0;
  341.         }
  342.     }
  343.     if (garg)
  344.         DISPOSE(gseq);
  345.     
  346.     return 1;
  347. }
  348.  
  349. imeth    int    gMatch(object mproto)
  350. {
  351.     ivType    *miv = ivPtr(mproto);
  352.     object    mseq, gseq, garg, marg;
  353.     int    n, error=0;
  354.  
  355. #if 0
  356.     print_args(iv, iArgs);
  357.     print_args(miv, miv->iArgs);
  358. #endif
  359.  
  360.     if (gCompare(miv->iRtn, iRtn))  {
  361.         error = 1;
  362.         vPrintf(stdoutStream, "Method %s and generic %s have different return types\n",
  363.             trunc_mname(gStringValue(miv->iName)),
  364.             gStringValue(iName));
  365.     }
  366.  
  367.     if (iException  ||  miv->iVararg  &&  iVararg)
  368.         return error;
  369.  
  370.     if (miv->iVararg  ||  iVararg)  {
  371.         vPrintf(stdoutStream, "Method %s and generic %s have different arguments\n",
  372.             trunc_mname(gStringValue(miv->iName)),
  373.             gStringValue(iName));
  374.         return 1;
  375.     }
  376.  
  377.     if (!miv->iProto)  {
  378.         vPrintf(stdoutStream, "Warning: Method %s has no prototype.\n",
  379.             trunc_mname(gStringValue(miv->iName)));
  380.         return error;
  381.     }
  382.  
  383.     if (!iProto)
  384.         return error;    /*  should never happen  */
  385.     
  386.     if (gSize(miv->iProto) != gSize(iProto))  {
  387.         vPrintf(stdoutStream, "Method %s and generic %s have a different number of arguments\n",
  388.             trunc_mname(gStringValue(miv->iName)),
  389.             gStringValue(iName));
  390.         return 1;
  391.     }
  392.  
  393.     mseq = gSequence(miv->iProto);
  394.     gseq = gSequence(iProto);
  395.     garg = (object) 1;    /*  any non-NULL  */
  396.     for (n=1 ; marg = gNext(mseq) ; ++n)  {
  397.         garg = gNext(gseq);
  398.         if (!garg)  {
  399.             error = 1;
  400.             vPrintf(stdoutStream, "Method %s and generic %s have a different number of arguments.\n",
  401.                 trunc_mname(gStringValue(miv->iName)),
  402.                 gStringValue(iName));
  403.             break;
  404.         }
  405. /*
  406.         if (streq(gStringValue(garg), "..."))
  407.             break;
  408. */
  409.         if (gCompare(marg, garg))  {
  410.             error = 1;
  411.             vPrintf(stdoutStream, "Method %s and generic %s have different argument types (%d)\n",
  412.                 trunc_mname(gStringValue(miv->iName)),
  413.                 gStringValue(iName), n);
  414.         }
  415.     }
  416.     if (marg)
  417.         DISPOSE(mseq);
  418.     if (garg)
  419.         DISPOSE(gseq);
  420.     
  421.     return error;
  422. }
  423.  
  424. imeth    gGetMGName()
  425. {
  426.     return iName;
  427. }
  428.  
  429. imeth    gChangeName(char *nm)
  430. {
  431.     if (iName)
  432.         gChangeStrValue(iName, nm);
  433.     else
  434.         iName = gNewWithStr(String, nm);
  435.     return self;
  436. }
  437.  
  438. imeth    gGetFixedName()
  439. {
  440.     return iFixedName;
  441. }
  442.  
  443. imeth    gChangeFixedName(char *nm)
  444. {
  445.     if (iFixedName)
  446.         gChangeStrValue(iFixedName, nm);
  447.     else
  448.         iFixedName = gNewWithStr(String, nm);
  449.     return self;
  450. }
  451.  
  452. imeth    gVarArg()
  453. {
  454.     iVararg = 1;
  455.     return self;
  456. }
  457.  
  458. imeth    int    gIsVarArg()
  459. {
  460.     return iNeedRest || iVararg;
  461. }
  462.  
  463. imeth    char    *gLastArg()
  464. {
  465.     return iLastArg && !iVararg ? gStringValue(iLastArg) : "self";
  466. }
  467.  
  468. imeth    gException()
  469. {
  470.     iException = 1;
  471.     return self;
  472. }
  473.  
  474.  
  475.  
  476. /*
  477.  *
  478.  *    Copyright (c) 1994-1996 Algorithms Corporation
  479.  *    3020 Liberty Hills Drive
  480.  *    Franklin, TN  37067
  481.  *
  482.  *    ALL RIGHTS RESERVED.
  483.  *
  484.  *
  485.  *
  486.  */
  487.